// Simple HTTP Request Library - Sends a simple HTTP request to a server, and returns the result
// Uses the Synapse library: http://synapse.ararat.cz

unit HTTPRequest;

interface

// Usage: GetHTTPRequest('benstoneonline.com', '/test.txt') to get http://benstoneonline.com/test.txt
// Result: the result, as a string.
function GetHTTPResult(strHost, strRequest : string) : string;

implementation

uses Classes, blcksock, synsock, strutils, sysutils, CRT;

function GetHTTPResult(strHost, strRequest : string) : string;
var
	httpRequest, httpResult, httpContent : string;
	contentLengthPos, contentPos, contentLength : integer;
	Sock : TTCPBlockSocket;
begin
	// Build a HTTP Request header
	httpRequest := 'GET ' + strRequest + ' HTTP/1.1'#13#10;
	httpRequest := httpRequest + 'Host: ' + strHost + #13#10;
	httpRequest := httpRequest + 'User-Agent: PascalRandomProxy/1.0';
	httpRequest := httpRequest + 'Connection: close' + #13#10;
	httpRequest := httpRequest + #13#10#13#10;
	
	// Create a socket
	Sock := TTCPBlockSocket.Create();
	
	// Connect to the server, assuming port 80. Assumptions are a bad thing.
	Sock.Connect(strHost, '80');
	
	// Send the request
	Sock.SendString(httpRequest);
	
	// Get the response
	httpResult := '';
	while Sock.CanRead(500) do
		httpResult:= httpResult + Sock.RecvPacket(4);
		
	
	if httpResult <> '' then
	begin
		// Check if there wasn't an error.
		// The first line of a HTTP response is in the format 'HTTP/1.1 Code Description'
		// Where Code = 200 if it's okay, 4xx,5xx if there's an error.
		if MidStr(httpResult, nPos(' ',httpResult,1)+1,nPos(' ',httpResult,2)-nPos(' ',httpResult,1)-1) <> '200' then
		begin
			result := '';
			exit;
		end;
	
		
		// Find the Content-Length header, which contains the length of the content.
		contentLengthPos := PosEx('Content-Length: ',httpResult);
		if contentLengthPos > 0 then
		begin
			// Found the Content-Length header, extract the number after it.
			TryStrToInt(MidStr(httpResult, contentLengthPos+16, PosEx(#13#10,httpResult, contentLengthPos) - contentLengthPos - 16), contentLength);

			// Content starts from the first double-CRLF
			contentPos := PosEx(#13#10#13#10,httpResult) + 4;
			// Get the content
			httpContent := MidStr(httpResult, contentPos, contentLength);
			result := httpContent;
		end
		else
			result := '';
	end;
	
	// Close and free the socket.
	Sock.CloseSocket();
	Sock.Free();
end;

end.